//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.ManagementStudioControls.WorkflowManagerModule
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Forms;
    using System.Windows.Input;
    using Microsoft.Research.ScientificWorkflow.TridentModel;
    using Microsoft.Research.ScientificWorkflow.UIDesigner;

    /// <summary>
    /// Days of week.
    /// </summary>
    [Flags]
    public enum DaysOfWeeks
    {
        /// <summary>
        /// No selection.
        /// </summary>
        None = 0x00,

        /// <summary>
        /// Sunday.
        /// </summary>
        Sunday = 0x01,

        /// <summary>
        /// Monday.
        /// </summary>
        Monday = 0x02,

        /// <summary>
        /// Tuesday.
        /// </summary>
        Tuesday = 0x04,

        /// <summary>
        /// Wednesday.
        /// </summary>
        Wednesday = 0x08,

        /// <summary>
        /// Thursday.
        /// </summary>
        Thursday = 0x10,

        /// <summary>
        /// Friday.
        /// </summary>
        Friday = 0x20,

        /// <summary>
        /// Saturday.
        /// </summary>
        Saturday = 0x40,
    }

    /// <summary>
    /// Various mode for scheduler.
    /// </summary>
    public enum ScheduleMode
    {
        /// <summary>
        /// Edit mode.
        /// </summary>
        Edit,

        /// <summary>
        /// Create new mode.
        /// </summary>
        New,

        /// <summary>
        /// Delete mode.
        /// </summary>
        Delete,
    }

    /// <summary>
    /// Interaction logic for SchedulerView.xaml
    /// </summary>
    public sealed partial class SchedulerView : Window
    {
        /// <summary>
        /// The datatype models for the composer control.
        /// </summary>
        private Dictionary<string, DataTypeModel> datatypeModels;

        /// <summary>
        /// The workflow model.
        /// </summary>
        private TridentWorkflowModel workflowModel;

        /// <summary>
        /// The workflow required parameters.
        /// </summary>
        private Collection<ParameterDescriptionModel> workflowRequiredParameters;

        /// <summary>
        /// The workflow output parameters.
        /// </summary>
        private Collection<ParameterDescriptionModel> workflowOutputParameters;

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="SchedulerView"/> class.
        /// </summary>
        /// <param name="passedId">Passed id.</param>
        /// <param name="scheduleMode">Schedule mode.</param>
        /// <param name="container">The container.</param>
        public SchedulerView()
        {
            InitializeComponent();
            this.brdrHeader.MouseLeftButtonDown += (sender, e) => this.DragMove();
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the start date time.
        /// Hosted windows' control property.
        /// </summary>
        /// <value>The start date time.</value>
        public DateTime StartDateTime
        {
            get
            {
                return startDateControl.Value;
            }
            set
            {
                startDateControl.Value = value;
            }
        }

        /// <summary>
        /// Gets or sets the end date time.
        /// Hosted windows' control property.
        /// </summary>
        /// <value>The end date time.</value>
        public DateTime EndDateTime
        {
            get
            {
                return endDateControl.Value;
            }
            set
            {
                if (value != DateTime.MinValue)
                {
                    endDateControl.Value = value;
                }
                else
                {
                    endDateControl.Value = DateTimePicker.MinimumDateTime;
                }
            }
        }

        #endregion

        #region Initialize

        /// <summary>
        /// Initialize the composercontrol and the property pane.
        /// </summary>
        /// <param name="workflowModel">The workflow model</param>
        /// <param name="datatypes">The datatypes info</param>
        public void Initialize(TridentWorkflowModel workflowModel, Dictionary<string, DataTypeModel> dataTypes)
        {
            this.workflowModel = workflowModel;
            this.workflowRequiredParameters = workflowModel.GetWorkflowRequiredParameters();

            this.workflowOutputParameters = workflowModel.GetWorkflowOutputParameters();

            this.datatypeModels = dataTypes;
            this.Loaded += new RoutedEventHandler(SchedulerView_Loaded);
        }

        /// <summary>
        /// The event handler for the loaded event of the execute workflow view. Initialize the composer control here.
        /// To make sure that the composer control is initialized once the window has been opened.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event arguments</param>
        void SchedulerView_Loaded(object sender, RoutedEventArgs e)
        {
            // Add the composer control.
            ComposerControl composerControl = new ComposerControl(null, null, this.datatypeModels, RenderMode.VisualizationMode, this);
            composerControl.Unloaded += new RoutedEventHandler(composerHost_Unloaded);
            composerControl.Loaded += new RoutedEventHandler(composerControl_Loaded);
            composerControl.Name = "scheduleWindowComposer";
            workflowModel.SwapSubsectionState += delegate(object origin, EventArgs args) { composerControl.SwapSubsectionState(origin); };

            this.composerHost.Child = composerControl;

            composerControl.LoadWorkflow(this.workflowModel, false);

            PropertyListControl workflowRequiredPropertyList = new PropertyListControl(this.workflowRequiredParameters, ValidationMode.All);
            System.Windows.Data.Binding propertyValidityBinding = new System.Windows.Data.Binding("PropertiesValid");
            propertyValidityBinding.Source = this.DataContext;
            propertyValidityBinding.Mode = BindingMode.TwoWay;
            workflowRequiredPropertyList.SetBinding(PropertyListControl.PropertiesValidProperty, propertyValidityBinding);

            OutputPropertyListControl worklfowOutputPropertyList = new OutputPropertyListControl(this.workflowOutputParameters, ControlMode.ReadOnly);

            Grid propertyPaneHostPanel = new Grid();
            propertyPaneHostPanel.RowDefinitions.Add(new RowDefinition());
            propertyPaneHostPanel.RowDefinitions.Add(new RowDefinition());

            // Add workflow required input property list to row 1.
            propertyPaneHostPanel.Children.Add(workflowRequiredPropertyList);
            workflowRequiredPropertyList.Height = 220;
            Grid.SetRow(workflowRequiredPropertyList, 0);

            // Add workflow output property list to row 2.
            propertyPaneHostPanel.Children.Add(worklfowOutputPropertyList);
            worklfowOutputPropertyList.Height = 220;
            Grid.SetRow(worklfowOutputPropertyList, 1);

            this.PropertyPaneHost.Child = propertyPaneHostPanel;
        }

        #endregion

        #region Helper Methods

        /// <summary>
        /// The event handler for the loaded event of the composer control.
        /// Register the name of the control in the main window.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event arguments</param>
        void composerControl_Loaded(object sender, RoutedEventArgs e)
        {
            ComposerControl control = sender as ComposerControl;
            System.Windows.Application.Current.MainWindow.RegisterName(control.Name, control);
        }

        /// <summary>
        /// The event handler for the unloaded event of the composer control.
        /// Unregister the name of the control from the main window.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event arguments</param>
        void composerHost_Unloaded(object sender, RoutedEventArgs e)
        {
            ComposerControl control = sender as ComposerControl;
            System.Windows.Application.Current.MainWindow.UnregisterName(control.Name);
        }

        /// <summary>
        /// Handles the PreviewKeyDown event of the TextBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
        private void TextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if ((e.Key >= Key.D0 && e.Key <= Key.D9) || e.Key == Key.Back ||
                e.Key == Key.Delete || e.Key == Key.Left || e.Key == Key.Right ||
                e.Key == Key.Tab || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }


        # endregion

        private void OnMachineListDropDownOpened(object sender, EventArgs e)
        {
            (this.DataContext as SchedulerViewPresenter).RefreshNodesCommand.Execute(false);
        }
    }
}
